package com.yao.mygranter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.TokenRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;

@Component
public class DingtalkAuthenticationProvider implements AuthenticationProvider, InitializingBean {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private UserDetailsService userDetailsService;


    @Autowired
    private ClientDetailsService clientDetailsService;





    private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();

    public DingtalkAuthenticationProvider() {
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.notNull(this.userDetailsService, "A UserDetailsService must be set");
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String authorizationCode = authentication.getPrincipal()!=null? (String) authentication.getPrincipal() :"";
        if(!StringUtils.hasText(authorizationCode)){
            return null;
        }

        TokenRequest tokenRequest = ((DingtalkAuthenticationToken) authentication).getTokenRequest();

//        userDetailsService.loadUserByUsername(tokenRequest.get);
        return null;
//
//        return createSuccessAuthentication(userAuth, authentication, userAuth);
    }

    protected Authentication createSuccessAuthentication(Object principal, Authentication authentication, UserDetails user) {
        DingtalkAuthenticationToken result = new DingtalkAuthenticationToken(
                principal,
                authoritiesMapper.mapAuthorities(user.getAuthorities()));
        result.setDetails(authentication.getDetails());

        return result;
    }


    protected Authentication createSuccessAuthentication(Object principal, Authentication authentication, Authentication user) {
        DingtalkAuthenticationToken result = new DingtalkAuthenticationToken(
                principal,
                authoritiesMapper.mapAuthorities(user.getAuthorities()));
        result.setDetails(authentication.getDetails());

        return result;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(DingtalkAuthenticationToken.class);
    }


    public ClientDetailsService getClientDetailsService() {
        return clientDetailsService;
    }



    public void setClientDetailsService(ClientDetailsService clientDetailsService) {
        this.clientDetailsService = clientDetailsService;
    }


    public UserDetailsService getUserDetailsService() {
        return userDetailsService;
    }

    public void setUserDetailsService(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }
}
